package edu.stu.cs.software.family.base.service;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

import java.io.Serializable;
import java.util.List;

import org.junit.Before;
import org.junit.Test;
import org.springframework.test.context.ContextConfiguration;

import edu.stu.cs.software.family.base.BaseAbstractTestCase;
import edu.stu.cs.software.family.base.domain.BaseEntity;
/**
 * The base class scans all classes under the dao and service project when other classes are called
 * This base class provides CRUD for all *test classes
 * @author Administrator
 *
 * @param <LG> the primary key of long for that type
 * @param <T> a type variable
 * @param <M> interface *Manager
 */
@ContextConfiguration(locations = { "classpath:/applicationContextTest-resources.xml",
		"classpath:/applicationContext-dao.xml", "classpath:/applicationContext-service.xml" })
public abstract class GenericManagerTestCase<LG extends Serializable, T extends BaseEntity<LG>, M extends GenericManager<T, LG>>
		extends BaseAbstractTestCase {

	protected T entity;
	protected List<T> list;
	protected M manager;

	private Class<T> persistentClass;

	public GenericManagerTestCase(final Class<T> persistentClass) {
		this.persistentClass = persistentClass;
	}

	/**
	 * Create a new entity before running it
	 * @throws Exception
	 */
	@Before
	public void setUp() throws Exception {
		this.entity = this.persistentClass.getDeclaredConstructor().newInstance();
	}

	/**
	 * The base class method applies to all classes CRUD
	 * @throws Exception
	 */
	@Test
	public void testCRUD() throws Exception {
		this.manager.deleteAll();
		int num = 50;
		int expect_id = 6;
		T expected = null;
		for (int i = 1; i <= num; i++) {
			T e = this.persistentClass.getDeclaredConstructor().newInstance();
			T saved = this.manager.save(e);
			assertNotNull(saved);
			if (i == expect_id) {
				expected = saved;
			}
		}
			// findById
			T reponse = this.manager.findById(expected.getId());
			assertEquals(expected, reponse);
			// test for method count()
			long count = this.manager.count();
			assertEquals(num, count);
		
	}
}